import { Injectable, NotFoundException } from '@nestjs/common';
import { DishEntity } from '@/entity/dish.entity';
import { CreateDishDto } from '@/modules/dish/dto/create-dish.dto';
import { Repository } from 'typeorm';
import { InjectRepository } from '@nestjs/typeorm';
import { UpdateDishDto } from '@/modules/dish/dto/update-dish.dto';
import { CategoryEntity } from '@/entity/category.entity';
import { RestaurantEntity } from '@/entity/restaurant.entity';

@Injectable()
export class DishService {
  constructor(
    @InjectRepository(DishEntity)
    private readonly dishRepository: Repository<DishEntity>,
    @InjectRepository(CategoryEntity)
    private readonly categoryRepository: Repository<CategoryEntity>,
    @InjectRepository(RestaurantEntity)
    private readonly restaurantRepository: Repository<RestaurantEntity>,
  ) {}

  async findAll(
    page = 1,
    limit = 10,
  ): Promise<{ list: DishEntity[]; total: number }> {
    const [data, total] = await this.dishRepository.findAndCount({
      skip: (page - 1) * limit,
      take: limit,
    });
    return {
      list: data,
      total,
    };
  }

  async findOne(id: number): Promise<DishEntity> {
    const dish = await this.dishRepository.findOne({ where: { id } });
    if (!dish) {
      throw new NotFoundException('未找到指定菜品内容');
    }
    return dish;
  }

  async create(createDishDto: CreateDishDto): Promise<DishEntity> {
    const category = await this.categoryRepository.query(
      `SELECT * FROM category_entity WHERE id = ${createDishDto.categoryId}`,
    );
    if (!category || category.length === 0) {
      throw new NotFoundException('未找到指定分类');
    }
    const { categoryId } = createDishDto;
    const maxSort = await this.dishRepository
      .createQueryBuilder('dish')
      .select('MAX(dish.sort)', 'maxSort')
      .where('dish.categoryId = :categoryId', { categoryId })
      .getRawOne();
    const sort = maxSort.maxSort !== null ? maxSort.maxSort + 1 : 0;
    const dish = new DishEntity();
    dish.name = createDishDto.name;
    dish.price = createDishDto.price;
    dish.description = createDishDto.description;
    dish.image = createDishDto.image;
    dish.categoryId = createDishDto.categoryId;
    dish.restaurantId = createDishDto.restaurantId;
    dish.stock = createDishDto.stock;
    dish.soldOut = createDishDto.soldOut;
    dish.sort = sort;
    return this.dishRepository.save(dish);
  }

  // async update(id: number, updateDishDto: UpdateDishDto): Promise<DishEntity> {
  //   const dish = await this.dishRepository.findOne({ where: { id } });
  //   if (!dish) {
  //     throw new NotFoundException('未找到指定菜品内容');
  //   }
  //   dish.name = updateDishDto.name;
  //   dish.price = updateDishDto.price;
  //   dish.description = updateDishDto.description;
  //   dish.image = updateDishDto.image;
  //   dish.categoryId = updateDishDto.categoryId;
  //   dish.restaurantId = updateDishDto.restaurantId;
  //   dish.stock = updateDishDto.stock;
  //   dish.soldOut = updateDishDto.soldOut;
  //   return this.dishRepository.save(dish);
  // }
  async update(id: number, updateDishDto: UpdateDishDto): Promise<DishEntity> {
    const dish = await this.dishRepository.findOne({ where: { id } });
    if (!dish) {
      throw new NotFoundException('指定菜品不存在');
    }

    const { categoryId, sort, ...rest } = updateDishDto;

    if (categoryId) {
      // 更新了菜品类别，需要将当前菜品的排序值重新梳理
      const category = await this.categoryRepository.findOne({
        where: { id: categoryId },
      });
      if (!category) {
        throw new NotFoundException('指定菜品类别不存在');
      }

      const dishList = await this.dishRepository.find({
        where: { categoryId },
        order: { sort: 'ASC' },
      });

      let orderIndex = 1;
      for (const d of dishList) {
        if (d.id === dish.id) {
          continue;
        }
        if (d.sort >= sort) {
          // 当前更新的菜品需要插入到此位置之前，因此其他菜品的排序值需要增加1
          await this.dishRepository.update(d.id, { sort: d.sort + 1 });
        } else {
          orderIndex = d.sort + 1;
        }
      }

      await this.dishRepository.update(dish.id, {
        categoryId,
        sort: orderIndex,
      });
    }

    return this.dishRepository.save({ ...dish, ...rest });
  }

  async delete(id: number) {
    const dish = await this.dishRepository.findOne({ where: { id } });
    if (!dish) {
      throw new NotFoundException('未找到指定菜品内容');
    }
    // 获取当前菜品类别下的菜品列表，并根据排序值进行排序
    const dishList = await this.dishRepository.find({
      where: { categoryId: dish.categoryId },
      order: { sort: 'ASC' },
    });
    const index = dishList.findIndex((d) => d.id === dish.id);
    // 更新当前菜品之后的菜品的排序值
    for (let i = index + 1; i < dishList.length; i++) {
      dishList[i].sort--;
      await this.dishRepository.save(dishList[i]);
    }
    await this.dishRepository.remove(dish);
    return `删除${dish.name}菜品内容成功`;
  }

  async findByCategoryId(categoryId: number): Promise<DishEntity[]> {
    const isRestaurant = await this.categoryRepository.query(
      `SELECT * FROM category_entity WHERE id = ${categoryId}`,
    );
    if (!isRestaurant || isRestaurant.length === 0) {
      throw new NotFoundException('未找到指定分类');
    }
    // return this.dishRepository.find({
    //   where: { categoryId },
    // });
    return this.dishRepository
      .createQueryBuilder('dish')
      .where('dish.categoryId = :categoryId', { categoryId })
      .andWhere('dish.sort >= 0') // 过滤掉被删除的菜品
      .orderBy('dish.sort', 'ASC') // 按照排序字段进行排序
      .getMany();
  }

  // 查询指定餐厅下的菜品
  async findByRestaurantId(restaurantId: number) {
    const isRestaurant = await this.restaurantRepository.query(
      `SELECT * FROM restaurant_entity WHERE id = ${restaurantId}`,
    );
    if (!isRestaurant || isRestaurant.length === 0) {
      throw new NotFoundException('未找到指定餐厅');
    }
    const result = await this.dishRepository.query(
      `SELECT * FROM dish_entity WHERE categoryId IN (SELECT id FROM category_entity WHERE restaurantId = ${restaurantId})`,
    );
    return result;
  }

  // 查询指定餐厅下的菜品类别为组的菜品内容列表
  async findByRestaurantIdGroupByCategory(restaurantId: number) {
    // 判断餐厅是否存在
    const isRestaurant = await this.restaurantRepository.query(
      `SELECT * FROM restaurant_entity WHERE id = ${restaurantId}`,
    );
    if (!isRestaurant || isRestaurant.length === 0) {
      throw new NotFoundException('未找到指定餐厅');
    }
    // 判断餐厅下是否有菜品
    const dishes = await this.dishRepository.query(
      `SELECT * FROM dish_entity WHERE categoryId IN (SELECT id FROM category_entity WHERE restaurantId = ${restaurantId})`,
    );
    if (!dishes || !dishes.length) {
      throw new NotFoundException('该餐厅暂无菜品');
    }
    // 查询餐厅下的菜品类别
    const categories = await this.categoryRepository.query(
      `SELECT * FROM category_entity WHERE restaurantId = ${restaurantId}`,
    );
    if (!categories || !categories.length) {
      throw new NotFoundException('该餐厅暂无菜品类别');
    }
    // 将菜品按照类别进行分组
    const dishList = categories.map((category) => {
      const dish = dishes.filter((dish) => dish.categoryId === category.id);
      return {
        categoryName: category.name,
        dishList: dish,
      };
    });
    return dishList;
  }
}
